package manage.action;

import m.appserver.ActionRedirect;
import m.appserver.AuthInfoUtil;
import m.appserver.ResponseUtil;
import m.common.action.ActionMeta;
import m.common.action.HtmlPageResult;
import m.common.action.RequestMeta;
import m.common.action.VueResult;
import m.common.model.util.ModelQueryList;
import m.common.model.util.QueryCondition;
import m.html.VueFormResult;
import m.html.VueListResult;
import m.html.element.Element;
import m.html.element.Text;
import m.html.element.attr.Align;
import m.html.element.attr.ButtonType;
import m.html.form.*;
import m.html.list.*;
import m.system.cache.CacheUtil;
import m.system.lang.PageInfo;
import m.system.util.JSONMessage;
import m.system.util.ObjectUtil;
import m.system.util.StringUtil;
import manage.model.AdminGroup;
import manage.model.AdminGroupLink;
import manage.model.AdminLogin;
import manage.run.ModuleInitRun;
import manage.service.AdminLoginService;
import manage.service.AdminSettingService;
import manage.util.CaptchaUtil;
import manage.util.DictionaryUtil;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

@ActionMeta(name="manage/adminLogin")
public class AdminLoginAction extends StatusAction {
	
	private AdminLogin model;
	private Boolean useKey;//新增时，是否使用编号作为主键
	private AdminGroupLink link;
	private String imageCode;
	private String password;
	public ActionRedirect admin() throws UnsupportedEncodingException{
		return new ActionRedirect(new HtmlPageResult(ModuleInitRun.getAdminPage()));
	}
	public ActionRedirect adminOpen(){
		return new ActionRedirect(new HtmlPageResult("page/open.html"));
	}
	public JSONMessage remind() {
		JSONMessage message=new JSONMessage(0);
		model=getSessionAdmin();
		//菜单消息
		Map<String,Object> menu= new HashMap<>();
		menu.put("A1101", "3");
		menu.put("A1102", "new");
		menu.put("Q51", "3");
		menu.put("Q5152", "hold");
		menu.put("P51", "5");
		message.push("menu", menu);
		return message;
	}
	public JSONMessage isLogin() throws Exception {
		JSONMessage message=new JSONMessage(0);
		message.push("codeVerify", CaptchaUtil.isMastVerify(AuthInfoUtil.getSession(getIpAddress())));
		message.push("model", getSessionAdmin());
		message.push("assist",getSessionAssist());
		message.push("orgGroup",getSessionOrgGroup());
		message.push("setting",getService(AdminSettingService.class).getAllSetting(ObjectUtil.getOid(getSessionAdmin())));
		message.push("powers",getAdminOperPower());
		return message;
	}
	public String getCaptchaCode() throws IOException {
		ResponseUtil response=getResponse();
		response.setHeader("Expires", 0);
        response.setHeader("Cache-Control", "no-store, no-cache,must-revalidate,post-check=0,pre-check=0");
        response.setHeader("Pragma", "no-cache");
        response.outBufferedImage(CaptchaUtil.getImageCode(AuthInfoUtil.getSession(getIpAddress())), "jpg");
		return "";
	}
	/**
	 * 登录
	 * 
	 */
	public JSONMessage doLogin() throws Exception {
		JSONMessage message=new JSONMessage(0);
		try {
			CaptchaUtil.verifyCaptcha(AuthInfoUtil.getSession(getIpAddress()), imageCode);
			model.setPassword(StringUtil.toMD5(model.getPassword()));
			model=getService(AdminLoginService.class).loginVerification(model);
			setSessionAdmin(model);
			getService(AdminLoginService.class).updateLastInfo(model, getIpAddress());
			message.push("model", model);
			message.push("assist",getSessionAssist());
			message.push("orgGroup",getSessionOrgGroup());
			CaptchaUtil.clearMastVerify(AuthInfoUtil.getSession(getIpAddress()));
			CaptchaUtil.clearCode(AuthInfoUtil.getSession(getIpAddress()));
			fillJSONResult(message,true,"登录成功");
		} catch (Exception e) {
			CaptchaUtil.setMastVerify(AuthInfoUtil.getSession(getIpAddress()));
			fillJSONResult(message,false,e);
			directLog("登录异常","登录失败",getRequest(),e);
		}
		message.push("codeVerify", CaptchaUtil.isMastVerify(AuthInfoUtil.getSession(getIpAddress())));
		return message;
	}
	/**
	 * 退出登录
	 * 
	 */
	public JSONMessage doLogout(){
		clearSessionAdmin();
		return new JSONMessage(0);
	}

	/**
	 * 保存
	 * 
	 */
	public JSONMessage doSave() throws Exception {
		systemLog("用户","保存用户信息");
		verifyAdminOperPower("manage_system_power");
		String msg=getService(AdminLoginService.class).save(model,link,password,useKey);
		CacheUtil.clear(AdminLogin.class, model.getOid());
		return new JSONMessage(0,msg);
	}
	/**
	 * 保存
	 * 
	 */
	public JSONMessage doSave4Self() throws Exception {
		systemLog("用户","保存自己的用户信息");
		AdminLogin admin=verifyAdminLogin();
		if(null==model||!model.getUsername().equals(admin.getUsername())){
			throw AuthInfoUtil.noPowerException;
		}
		model.setAdminGroup(admin.getAdminGroup());
		String msg=getService(AdminLoginService.class).save(model,password);
		CacheUtil.clear(AdminLogin.class, admin.getOid());
		return new JSONMessage(0,msg);
	}
	@RequestMeta(params = {"realname","orgGroup","roleGroup"})
	public JSONMessage getAllAdmin(String realname,String orgGroup,String roleGroup) throws Exception {
		verifyAdminOperPower(getStatusPower());
		PageInfo pageInfo=getService(AdminLoginService.class).getAll(this.getPage(),realname,orgGroup,roleGroup);
		return new JSONMessage(0)
				.push("list", pageInfo.getList())
				.push("count",pageInfo.getCount());
	}
	public VueResult toEdit4Self() {
		ModelForm form=new ModelForm("登录信息",2)
		.addItem(
			FormHtml.ins("所属部门",
					new Text("{{model.username}}")
			).setSpan(2),
			FormInput.input("真实姓名","model.realname").setPlaceholder("请输入真实姓名").setRequired(true),
			FormInput.selectImage("头像","model","headImage","defaultHead"),
			FormInput.password("密码","model.password").setPlaceholder("请输入密码")
					.setDescription("不填写密码则不会修改原密码"),
			FormInput.password("重复密码","password").setPlaceholder("请再次输入密码")
					.setDescription("不填写密码则不会修改原密码")
		)
		.addData("model",getSessionAdmin())
		.addData("password","")
		.addButton(
			FormButton.pri("保存","save")
		)
		.addMethod(
			FormEvent.backTrue,
			FormEvent.doJson("save",actionUrl("doSave4Self"),"{model:this.model,password:this.password}")
				.success("backTrue")
		);
		VueFormResult result=new VueFormResult();
		return result.addForm(form);
	}
	public VueResult toEdit() throws Exception {
		verifyAdminOperPower("manage_system_power");
		if(null==model) {
			model=new AdminLogin();
		}else if(!StringUtil.isSpace(model.getOid())){
			model=ModelQueryList.getModel(model,"*","headImage.*","adminGroup.*");
		}
		if(null!=link&&null!=link.getAdminGroup()) {
			link.setAdminGroup(ModelQueryList.getModel(link.getAdminGroup(), "*","parent.*"));
		}
		ModelForm form=new ModelForm("管理员信息",2)
			.addItem(
				FormTest.test("link&&link.adminGroup",
					FormHtml.ins("所属部门",
						Element.toElement(
							Element.tag("span").A("v-if","link.adminGroup.parent&&link.adminGroup.parent.oid")
							.A("style","padding-right:10px;").E("{{link.adminGroup.parent.name}}"),
							Element.tag("span").A("v-if","link.adminGroup.oid")
							.E("{{link.adminGroup.name}}")
						)
					).setSpan(2)
				),
				FormInput.input("编号","model.userNo").setPlaceholder("请输入编号").setRequired(true).setDisabled("model.oid&&model.oid==model.userNo"),
				FormTest.test("!model.oid",FormInput.checkBox("编号主键","useKey").setPlaceholder("使用编号作为主键"))
					.other(FormHtml.ins("主键","{{model.oid}}")),
				FormInput.input("用户名","model.username").setPlaceholder("请输入用户名").setRequired(true).setDisabled("model.oid!=null"),
				FormInput.input("真实姓名","model.realname").setPlaceholder("请输入真实姓名").setRequired(true),
				FormInput.password("密码","model.password").setPlaceholder("请输入密码")
						.setDescription("不填写密码则不会修改原密码"),
				FormInput.password("重复密码","password").setPlaceholder("请再次输入密码")
						.setDescription("不填写密码则不会修改原密码"),
				FormInput.select("管理员组","model.adminGroup.oid","manage.model.AdminGroup:A").setPlaceholder("请选择管理员组"),
				FormInput.selectImage("头像","model","headImage","defaultHead")
			)
			.addData("model",model)
			.addData("useKey",true)
			.addData("password","")
			.addData("link",link)
			.addButton(
				FormButton.pri("保存","save")
			)
			.addMethod(
				FormEvent.backTrue,
				FormEvent.doJson("save",actionUrl("doSave"),"{model:this.model,useKey:this.useKey,link:this.link,password:this.password}")
					.success("backTrue")
			);

		VueFormResult result=new VueFormResult();
		return result.addForm(form);
	}
	public VueResult adminLoginList() throws Exception{
		verifyMenu("A1101","A1102");
		boolean power=hasAdminOperPower(getStatusPower());
		String adminGroupOid=getParamsValue("adminGroupOid");
		VueListResult result=getVueListResult("管理员列表",AdminLogin.class,actionUrl("adminLoginList"));
		result.setSubTitle("添加或者编辑管理员信息。");
		result.setHeight(-1);
		result.setPageSize(20);
		result.setFunction(true,true);
		//result.setSelection("oid", false,"record.oid=='1'");
		result.addCol(toIndexColumn());
		result.addCol(toTextColumn("用户编号", "userNo",true));
		if(power) result.addCol(toLinkColumn("用户名", "username",
			new ListEvent("page/base/viewGroupMenuPage.js", EventType.POPOVER,800)
				.addParam("adminOid","oid")
		).setSort(true));
		else result.addCol(toTextColumn("用户名", "username",true));
		result.addCol(toTextColumn("真实姓名", "realname",true));
		if(StringUtil.isSpace(adminGroupOid)) {
			result.addCol(toTextColumn("管理员组", "adminGroup.oid",true).setDictType(AdminGroup.class,"A"));
		}else {
			result.addCondition(QueryCondition.eq("adminGroup.oid", adminGroupOid));
		}
		result.addCol(toDateTimeColumn("创建时间", "createDate",160,true).setSort(true));
		result.addCol(toDateTimeColumn("最后登录时间", "lastLoginTime",160,true).setSort(true));
		result.addCol(toNumberColumn("登录次数", "loginCount").setNumberFormat("#,##0").setCount(ListCount.SUM));
		result.addCol(toStatusColumn(power));
		if(power) result.addCol(toSpaceColumn("操作",100,
			ListButton.drawer("修改", ButtonType.PRIMARY,actionUrl("toEdit"),600, SuccessMethod.REFRESH)
				.addParam("model.oid","oid")
		).setFixed(Align.RIGHT));
		if(power) result.addButton(
			ListButton.modal("添加",ButtonType.PRIMARY,actionUrl("toEdit"),600,SuccessMethod.REFRESH)
				.addQueryParam("model.adminGroup.oid","adminGroupOid")
		);
		return result;
	}

	/**
	 * 选择页面示例
	 */
	public VueResult selectUser(){
		String selected=getParamsValue("selected");
		VueListResult result=getVueListResult("管理员列表",AdminLogin.class,actionUrl("selectUser"));
		result.setDescribe("<a-alert :message=\"'已选择'+concatSelected(item=>item.realname)+'，共登录'+sumSelected(item=>item.loginCount)+'次。'\" style=\"margin-bottom:10px;\" />");
		result.setHeight(-1);
		result.setPageSize(20);
		result.setFunction(true,true);
		result.setSelection("oid", "one".equals(getParamsValue("selectMode","")));
		result.addCol(toIndexColumn());
		result.addCol(toTextColumn("用户编号", "userNo",true));
		result.addCol(toLinkColumn("用户名", "username",
				new ListEvent("page/base/viewGroupMenuPage.js", EventType.POPOVER,800)
						.addParam("adminOid","oid")
				));
		result.addCol(toTextColumn("真实姓名", "realname",true));
		result.addCol(toTextColumn("管理员组", "adminGroup.oid",true).setDictType(AdminGroup.class,"A"));
		result.addCol(toDateTimeColumn("创建时间", "createDate",160,true).setSort(true));
		result.addCol(toDateTimeColumn("最后登录时间", "lastLoginTime",160,true).setSort(true));
		result.addCol(toNumberColumn("登录次数", "loginCount").setNumberFormat("#,##0").setCount(ListCount.SUM));
		result.addButton(
			ListButton.back("选择", ButtonType.PRIMARY).addParam("","oid"));
//		ListButton.ajax("选择", ButtonType.PRIMARY,"").addParam("","oid"));
		return result;
	}

	@Override
	public void doRecoveryCallback() {
		DictionaryUtil.clear(AdminLogin.class);
	}

	@Override
	public void doDisableCallback() {
		DictionaryUtil.clear(AdminLogin.class);
	}

	public Boolean getUseKey() {
		return useKey;
	}

	public void setUseKey(Boolean useKey) {
		this.useKey = useKey;
	}

	public AdminLogin getModel() {
		return model;
	}
	public void setModel(AdminLogin model) {
		this.model = model;
	}
	@Override
	public String[] getStatusPower() {
		return new String[]{"manage_system_power"};
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getImageCode() {
		return imageCode;
	}
	public void setImageCode(String imageCode) {
		this.imageCode = imageCode;
	}
	public AdminGroupLink getLink() {
		return link;
	}
	public void setLink(AdminGroupLink link) {
		this.link = link;
	}
}
